package com.github.aloxc.plugin.restplus.test;


import com.intellij.execution.ExecutionException;
import com.intellij.ide.script.IdeScriptEngine;
import com.intellij.ide.script.IdeScriptEngineManager;
import com.intellij.ide.script.IdeScriptException;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.text.StringUtil;
import org.apache.http.entity.ContentType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
/**
 * @author leero
 */
public class HttpResponseHandlerNashornExecutor
        implements HttpClientResponseHandlerExecutor {
    private final IdeScriptEngine myEngine;

    public HttpResponseHandlerNashornExecutor(@NotNull IdeScriptEngine engine) {
        this.myEngine = engine;
    }

    @Nullable
    public static HttpResponseHandlerNashornExecutor create() {
        IdeScriptEngine engine = IdeScriptEngineManager.getInstance().getEngineByFileExtension("js", null);
        return (engine != null) ? new HttpResponseHandlerNashornExecutor(engine) : null;
    }

    @Override
    @NotNull
    public HttpResponseExecutionResult execute(@NotNull RestResponse session, @NotNull RestClientResponse response, @NotNull String script) throws ExecutionException {
        // todo 执行脚本
        this.myEngine.setBinding("HTTP_CLIENT_SESSION", session);
        boolean isJson = StringUtil.equalsIgnoreCase(response.getContentType().getMimeType(), ContentType.APPLICATION_JSON.getMimeType());
        String responseBody = isJson ? "JSON.parse(HTTP_CLIENT_SESSION.content)" : "HTTP_CLIENT_SESSION.content";
//        String variableDefinition = "var client = { global: HTTP_CLIENT_SESSION.client.global };client.test = function(name, func) { return HTTP_CLIENT_SESSION.client.test(name, func || null);};client.assert = function(res, message) { return HTTP_CLIENT_SESSION.client.assertTrue(res, message || \"Assert failed\");};client.log = function(text) { print(text); };var response = { body: " + responseBody + ", status: HTTP_CLIENT_SESSION.statusCode, headers: HTTP_CLIENT_SESSION.headers, contentType: HTTP_CLIENT_SESSION.contentType};";
        String variableDefinition = "var client = { global: HTTP_CLIENT_SESSION.client.global,name:null };" +
                "client.log = function(text) { HTTP_CLIENT_SESSION.client.print(text); };" +
                "client.test = function(nam, func) {" +
                "this.name = nam;" +
                "HTTP_CLIENT_SESSION.client.func(func.toLocaleString());" +
                "return HTTP_CLIENT_SESSION.client.test(nam, func || null);};" +
                "client.assert = function(res, message) { return HTTP_CLIENT_SESSION.client.assertTrue(res, message || \"Assert failed\",this.name);};" +
                "var response = { body: " + responseBody + ", " +
                "status: HTTP_CLIENT_SESSION.statusCode, " +
                "headers: HTTP_CLIENT_SESSION.headers, " +
                "contentType: HTTP_CLIENT_SESSION.contentType};";
        try {
            this.myEngine.eval(variableDefinition + script);
            return new HttpResponseExecutionResult(session.getClient().getTestList(),session.getClient().getPrintList());
        } catch (IdeScriptException e) {
            ProgressManager.checkCanceled();
            try {
                this.myEngine.getStdErr().write(e.getMessage());
            } catch (IOException ioexception) {
            }
            throw new ExecutionException(e.getMessage());
        }
    }

    @Override
    public void close() {
    }
}